package com.crk.yiyuanguahao.service.impl;


import com.crk.yiyuanguahao.dao.FunctionDao;
import com.crk.yiyuanguahao.dao.ResAuthDao;
import com.crk.yiyuanguahao.dao.RoleAuthDao;
import com.crk.yiyuanguahao.dao.UserDao;
import com.crk.yiyuanguahao.entity.Function;
import com.crk.yiyuanguahao.entity.ResAuth;
import com.crk.yiyuanguahao.entity.RoleAuth;
import com.crk.yiyuanguahao.entity.User;
import com.crk.yiyuanguahao.entity.menu.SysFunctionMenuDto;
import com.crk.yiyuanguahao.entity.menu.SysFunctionTreeDto;
import com.crk.yiyuanguahao.service.FunctionService;
import com.crk.yiyuanguahao.service.ResAuthService;
import com.crk.yiyuanguahao.util.ResponseEnum;
import com.crk.yiyuanguahao.util.ResponseResult;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @Author: 程荣凯
 * @Date: 2019/3/21 17:38
 */
@Service
public class ResAuthServiceImpl implements ResAuthService {
    @Autowired
    ResAuthDao resAuthDao;
    @Autowired
    FunctionDao functionDao;
    @Autowired
    RoleAuthDao roleAuthDao;
    @Autowired
    FunctionService functionService;
    @Autowired
    UserDao userDao;
    @Autowired
    DataSourceTransactionManager transactionManager;

//    @Autowired
//    private Config config;

    @Override
    public ResponseResult addResAuth(ResAuth resAuth) {
        if (null == resAuth){
            return ResponseResult.fail(ResponseEnum.PARAM_ERROR);
        }
        List<ResAuth> roleAuth = (List<ResAuth>)getResAuth(resAuth.getRoleId(), resAuth.getFunctionId())
                .getData();
        if (null != roleAuth && roleAuth.size()>0){
            return ResponseResult.fail(ResponseEnum.DATAEXIST_ERROR);
        }
        try {
            resAuth.setCreateTime(new Date());
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            resAuth.setCreator(user.getId());
            resAuth.setUpdateTime(new Date());
            resAuth.setUpdator(user.getId());
            int insert = resAuthDao.insert(resAuth);
            if (insert>0){
                return ResponseResult.success();
            }else{
                return ResponseResult.fail();
            }
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }
    }

    @Override
    @Transactional
    public ResponseResult batchAddResAuth(int roleId, List<HashMap<String, Integer>> res) {
        for (HashMap<String, Integer> map : res) {
            ResAuth resAuth = new ResAuth();
            resAuth.setRoleId(roleId);
            resAuth.setStatus((short)1);
            resAuth.setFunctionId(map.get("functionId"));
            ResponseResult responseResult = addResAuth(resAuth);
            if (!ResponseResult.isSuccess(responseResult)){
                break;
            }
        }
        return ResponseResult.success();
    }

    @Override
    public ResponseResult updateResAuth(ResAuth resAuth) {
        if (null == resAuth){
            return ResponseResult.fail(ResponseEnum.PARAM_ERROR);
        }
        try {
            int update = resAuthDao.updateByPrimaryKey(resAuth);
            if (update>0){
                return ResponseResult.success();
            }else{
                return ResponseResult.fail();
            }
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }
    }

    @Override
    @Transactional
    public ResponseResult batchUpdateResAuth(int roleId, List<HashMap<String, Integer>> res) {
        //删除原有权限
        resAuthDao.deleteByRoleId(roleId);
        ResponseResult responseResult = batchAddResAuth(roleId, res);
        if (!ResponseResult.isSuccess(responseResult)){
            return ResponseResult.fail();
        }
        return ResponseResult.success();
    }

    @Override
    public ResponseResult deleteResAuth(int resAuthId) {
        if (StringUtils.isEmpty(resAuthId) ){
            ResponseResult.fail(ResponseEnum.PARAM_ERROR);
        }
        try {
            int count = resAuthDao.deleteByPrimaryKey(resAuthId);
            if (count>0){
                return ResponseResult.success();
            }else{
                return ResponseResult.fail();
            }
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }
    }

    @Override
    public ResponseResult queryResAuthList(int userId) {
        try {
            List<RoleAuth> roleAuthList = roleAuthDao.getRoleAuthList(userId, 1);
            List<Function> result = new ArrayList<Function>();
            if (null != roleAuthList && !roleAuthList.isEmpty()){
                for (RoleAuth roleAuth : roleAuthList) {
                    List<Function> sysResAuths = resAuthDao.queryFunctionList(roleAuth.getRoleId());
                    if (!StringUtils.isEmpty(sysResAuths)){
                        result.addAll(sysResAuths);
                    }
                }
            }
            return ResponseResult.success(result);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }

    }

    @Override
    public ResponseResult queryResListTreeByRole(int roleId,int functionId,int type) {
        try {
            List<ResAuth> sysResAuths = resAuthDao.queryResAuthList(roleId);
            List<SysFunctionTreeDto> list = new ArrayList<SysFunctionTreeDto>();
            List<SysFunctionTreeDto> childrenTree = getChildrenTree(list, sysResAuths, functionId, type);
            return ResponseResult.success(childrenTree);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }

    }


    public ResponseResult getResAuth(int roleId,int parentFunction) {
        try {
            List<ResAuth> sysResAuths = resAuthDao.getResAuthListByParent(roleId,parentFunction);
            if (null != sysResAuths && sysResAuths.size()>0){
                return ResponseResult.success(sysResAuths);
            }else{
                return ResponseResult.fail();
            }

        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }
    }

    @Override
    public List<SysFunctionTreeDto> getChildrenTree(List<SysFunctionTreeDto> functionList,List<ResAuth> sysResAuths
            ,int functionId,int type){
        List<Function> sysFunctionList = functionDao.selectByParentId(functionId, type);
        if (null == sysFunctionList || sysFunctionList.size() == 0){
            return functionList;
        }else {
            HashSet<Integer> set = new HashSet<Integer>();
            if (null != sysResAuths && sysResAuths.size() >0){
                //判断是否被选中
                for (ResAuth ResAuth : sysResAuths) {
                    set.add(ResAuth.getFunctionId());
                }
            }
            for (Function function : sysFunctionList) {
                SysFunctionTreeDto sysFunctionTreeDto = new SysFunctionTreeDto();
                sysFunctionTreeDto.setKey(function.getId());
                sysFunctionTreeDto.setLabel(function.getFunctionName());
                sysFunctionTreeDto.setSpread(false);
                sysFunctionTreeDto.setChecked(false);
                if (set.contains(function.getId())){
                    sysFunctionTreeDto.setChecked(true);
                }
                List<Function> sysFunctions = functionDao.selectByParentId(function.getId(), type);
                if (null != sysFunctions && sysFunctions.size()>0){
                    List<SysFunctionTreeDto> childrenList = new ArrayList<SysFunctionTreeDto>();
                    sysFunctionTreeDto.setChildren(getChildrenTree(childrenList,sysResAuths,function.getId(),type));
                    sysFunctionTreeDto.setChecked(false);
                    functionList.add(sysFunctionTreeDto);
                }else {
                    functionList.add(sysFunctionTreeDto);
                    continue;
                }
            }
            return functionList;
        }

    }

    /**
     * 查询子功能
     *
     * @param pId  父功能id
     * @param type 功能类型
     * @return
     */
    @Override
    public List<SysFunctionMenuDto> queryMenuListByPid(List<SysFunctionMenuDto> functionList, HashSet<Integer> resAuths, int pId, int type) {
        if (null == resAuths && resAuths.size()==0){
            return null;
        }
        List<Function> sysFunctionList = functionDao.selectByParentId(pId, type);
        if (null == sysFunctionList || sysFunctionList.size() == 0){
            return functionList;
        }else {
            for (Function function : sysFunctionList) {
                if (!resAuths.contains(function.getId())){
                    continue;
                }
                SysFunctionMenuDto sysFunctionMenuDto = new SysFunctionMenuDto();
                sysFunctionMenuDto.setKey(function.getId());
                sysFunctionMenuDto.setName(function.getFunctionName());
                sysFunctionMenuDto.setUrl(function.getFunctionPath());
                sysFunctionMenuDto.setType("1");
                List<Function> sysFunctions = functionDao.selectByParentId(function.getId(), type);
                if (null != sysFunctions && sysFunctions.size()>0){
                    sysFunctionMenuDto.setType("0");
                    List<SysFunctionMenuDto> childrenList = new ArrayList<SysFunctionMenuDto>();
                    sysFunctionMenuDto.setList(queryMenuListByPid(childrenList,resAuths,function.getId(),type));
                    functionList.add(sysFunctionMenuDto);
                }else {
                    functionList.add(sysFunctionMenuDto);
                    continue;
                }
            }
            return functionList;
        }
    }

    /**
     * 查询子菜单（不查询子集）
     * @param pId 父id
     * @param type 类型
     * @return
     */
    @Override
    public List<Function> selectByParentId(int pId,int type){
        List<Function> functionList = functionDao.selectByParentId(pId, type);
        return functionList;
    }

    /**
     * 查询子菜单（不查询子集）
     *
     * @param pId  父id
     * @param type 类型
     * @return
     */
    @Override
    public List<Function> selectByParentIdPlus(int pId, int type,int userId) {
        List<Function> result = new ArrayList<Function>();
        List<Function> functionList = selectByParentId(pId,type);
        ResponseResult roleAuthList = queryResAuthList(userId);
        if (null == roleAuthList || !ResponseResult.isSuccess(roleAuthList) || roleAuthList.getData() == null){
            return null;
        }
        User user = userDao.selectByPrimaryKey(userId);
        Set<Integer> integerSet = new HashSet<>();
        List<Function> functions = (List<Function>)roleAuthList.getData();
        for (Function function : functionList) {
            for (Function sysFunction : functions) {
                if (sysFunction.getId().equals(function.getId())){
                    if (integerSet.isEmpty() || !integerSet.contains(function.getId())){
                        result.add(function);
                        integerSet.add(function.getId());
                    }
                    continue;
                }
            }
        }
        return result;
    }

    /**
     * 查询菜单
     *
     * @param userId
     * @param type
     * @return
     */
    @Override
    public ResponseResult getFunctionByUser(int userId, int type,int currentId) {
        try {
            List<Function> functionByUser = resAuthDao.getFunctionByUser(userId, type,currentId);
            return ResponseResult.success(functionByUser);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }
    }

    /**
     * 查询菜单
     *
     * @param userId
     * @param type
     * @return
     */
    @Override
    public ResponseResult getFunctionTreeByUser(int userId, int type,int currentId) {
        try {
            List<Function> functionByUser = resAuthDao.getFunctionByUser(userId, type,currentId);
            List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
            for (Function sysFunction : functionByUser) {
                HashMap<String,Object> temp = new HashMap<String,Object>();
                temp.put("key",sysFunction.getId());
                temp.put("label",sysFunction.getFunctionName());
                list.add(temp);
            }
            return ResponseResult.success(list);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }
    }

    /**
     * 查询菜单
     *
     * @param roleId
     * @param type
     * @return
     */
    @Override
    public ResponseResult getFunctionTreeByRole(int roleId, int type,Integer currentId) {
        try {
            List<Function> functionByUser = resAuthDao.getFunctionByRole(roleId, type,currentId);
            List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
            for (Function sysFunction : functionByUser) {
                HashMap<String,Object> temp = new HashMap<String,Object>();
                temp.put("key",sysFunction.getId());
                temp.put("label",sysFunction.getFunctionName());
                list.add(temp);
            }
            return ResponseResult.success(list);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.fail();
        }
    }

    /**
     * 查询数据权限规则
     *
     * @param userId 用户id
     * @param module 所属模块
     * @return
     */
    @Override
    public ResponseResult getDataAuthRule(int userId, int module) {
        //综合查询
        List<RoleAuth> roleAuthList = roleAuthDao.getRoleAuthList(userId, 1);
        if(null != roleAuthList && !roleAuthList.isEmpty()){
            String auth = "";
            HashMap<String,Object> condition = new HashMap<String,Object>();
            condition.put("type","3");
            condition.put("module",module);
            for (RoleAuth roleAuth : roleAuthList) {
                int roleId = roleAuth.getRoleId();
                condition.put("roleId",roleId);
                List<Function> functions = resAuthDao.getDataRule(condition);
                if(null != functions && functions.size()>0){
                    for (Function function : functions) {
                        if (function.getFunctionPath().equals("1")){
                            auth = function.getFunctionPath();
                            continue;
                        }else if (function.getFunctionPath().equals("2")){
                            auth = function.getFunctionPath();
                            continue;
                        }else {
                            auth = function.getFunctionPath();
                            break;
                        }
                    }

                }
            }
            return ResponseResult.success(auth);
        }else {
            return ResponseResult.fail();
        }
    }


}
